﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Physis.Core.Entity {

    public class Entity : CoreObject {
        
        #region Private Properties 

        private Boolean person = true;

        private String nameLast = String.Empty;

        private String nameFirst = String.Empty;

        private String nameMiddle = String.Empty;

        private String nameSuffix = String.Empty;

        private String uniqueId = String.Empty;

        private String federalTaxId = String.Empty;

        private String legacyId = String.Empty;

        #endregion 


        #region Public Properties 

        public virtual Enumerations.EntityType EntityType { get { return Enumerations.EntityType.NotSpecified; } }

        public virtual Boolean Person { get { return person; } set { person = value; } }

        public virtual Boolean CanBePerson { get { return true; } }

        public String NameLast { get { return nameLast; } set { nameLast = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.NameLast); } }

        public String NameFirst { get { return nameFirst; } set { nameFirst = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.NameFirst); } }

        public String NameMiddle { get { return nameMiddle; } set { nameMiddle = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.NameMiddle); } }

        public String NameSuffix { get { return nameSuffix; } set { nameSuffix = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.NameSuffix); } }

        public String UniqueId { get { return uniqueId; } set { uniqueId = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.BusinessId); } }

        public String FederalTaxId { get { return federalTaxId; } set { federalTaxId = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.FederalTaxId); } }

        public String LegacyId { get { return legacyId; } set { legacyId = Data.Functions.SetValueMaxLength (value, Data.DataTypeConstants.BusinessId); } }

        #endregion 


        #region Constructors

        protected Entity () { return; }

        public Entity (Application forApplication) : base (forApplication) { return; }

        public Entity (Application forApplication, Int64 forId) : base (forApplication, forId) { return; }

        #endregion 
        

        #region Database Functions

        protected override Dictionary<String, String> Validate () {

            Dictionary<String, String> validationErrors = new Dictionary<String, String> ();


            // DO NOT CALL BASE VALIDATOR SINCE THE NAME AND DESCRIPTION ARE EVALUATED DIFFERENTLY 


            if ((Person) && (String.IsNullOrWhiteSpace (NameLast))) { validationErrors.Add ("NameLast", "Empty or missing value for last name of a person."); }

            if ((Person) && (String.IsNullOrWhiteSpace (NameFirst))) { validationErrors.Add ("NameFirst", "Empty or missing value for first name of a person."); }

            if ((!Person) && (String.IsNullOrWhiteSpace (Name))) { validationErrors.Add ("Name", "Empty or missing value for name of a non-person entity."); }


            return validationErrors;

        }

        public override void MapDataFields (System.Data.DataRow currentRow) {

            base.MapDataFields (currentRow);

                        
            Person = Data.Readers.DataReader.BooleanFromDatabase (currentRow, "Person");

            NameLast = Data.Readers.DataReader.StringFromDatabase (currentRow, "NameLast");

            NameFirst = Data.Readers.DataReader.StringFromDatabase (currentRow, "NameFirst");

            NameMiddle = Data.Readers.DataReader.StringFromDatabase (currentRow, "NameMiddle");

            NameSuffix = Data.Readers.DataReader.StringFromDatabase (currentRow, "NameSuffix");

            UniqueId = Data.Readers.DataReader.StringFromDatabase (currentRow, "UniqueId");

            FederalTaxId = Data.Readers.DataReader.StringFromDatabase (currentRow, "FederalTaxId");

            LegacyId = Data.Readers.DataReader.StringFromDatabase (currentRow, "LegacyId");


            return;

        }

        public override Boolean Save () { return Save (0); }

        protected Boolean Save (Int64 entityId = 0) {

            Boolean success = false;

            Boolean useTransaction = (Application.EnvironmentDatabase.OpenTransactions == 0);

            try {

                Dictionary<String, String> validationErrors = Validate ();

                if (validationErrors.Count > 0) {

                    Application.SetLastException (new Exception ("Invalid [" + validationErrors.Keys.First () + "]: " + validationErrors.Values.First ()));

                    return false;

                }

                UpdateModifiedToSessionUser ();


                if (useTransaction) { Application.EnvironmentDatabase.BeginTransaction (); }


                System.Data.IDbCommand command = Application.EnvironmentDatabase.CreateCommand ("Entity_InsertUpdate"); // MAKE SURE TO USE FULLY QUALIFIED NAME SINCE THIS IS A BASE OBJECT 

                command.CommandType = System.Data.CommandType.StoredProcedure;


                Application.EnvironmentDatabase.AppendCommandParameter (command, "Id", ((entityId == 0) ? Id : entityId)); // ALLOW A DERIVED CLASS TO PASS IN AN ENTITY ID 

                Application.EnvironmentDatabase.AppendCommandParameter (command, "Name", Name, 60);


                Application.EnvironmentDatabase.AppendCommandParameter (command, "EntityType", ((Int32)EntityType));

                Application.EnvironmentDatabase.AppendCommandParameter (command, "Person", Person);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "NameLast", NameLast, 60);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "NameFirst", NameFirst, 60);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "NameMiddle", NameMiddle, 60);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "NameSuffix", NameSuffix, 60);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "UniqueId", ((String.IsNullOrWhiteSpace (UniqueId)) ? null : UniqueId), 20); // ALLOW THIS TO PASS AS A NULL

                Application.EnvironmentDatabase.AppendCommandParameter (command, "FederalTaxId", FederalTaxId, 9);

                Application.EnvironmentDatabase.AppendCommandParameter (command, "LegacyId", LegacyId, 20);
                
                
                Application.EnvironmentDatabase.AppendCommandParameter (command, "ModifiedId", Application.Session.UserAccountName, 60);

                success = (command.ExecuteNonQuery () > 0);

                if (success) { SetIdentity (); }


                if (useTransaction) { Application.EnvironmentDatabase.CommitTransaction (); }

            }

            catch (Exception exception) {

                if (useTransaction) { Application.EnvironmentDatabase.RollbackTransaction (); }

                success = false;

                Application.SetLastException (exception);

            }

            return success;

        }

        #endregion 


        #region Public Methods 


        #endregion 


    }

}
